package com.wuhao.code.check.processors

import com.aegis.mybatis.xmlless.annotations.XmllessMethod
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.codeStyle.CodeStyleSettings
import com.intellij.psi.impl.source.codeStyle.PostFormatProcessor
import com.wuhao.code.check.highlight.XmllessMethodAnnotationHighlighter
import org.jetbrains.kotlin.psi.psiUtil.endOffset

/**
 * 修复java文件中的空白行
 * @author 吴昊
 * @since 1.1.2
 */
class FixXmllessMethodPostProcessor : PostFormatProcessor {

  override fun processElement(source: PsiElement, settings: CodeStyleSettings): PsiElement {
    return source
  }

  override fun processText(source: PsiFile, rangeToReformat: TextRange, settings: CodeStyleSettings): TextRange {
    source.accept(object : JavaRecursiveElementVisitor() {

      override fun visitAnnotation(annotation: PsiAnnotation) {
        if (annotation.qualifiedName != XmllessMethod::class.java.name) {
          return
        }
        super.visitAnnotation(annotation)
      }

      override fun visitNameValuePair(pair: PsiNameValuePair) {
        if (pair.name in listOf("conditions")) {
          super.visitNameValuePair(pair)
        }
      }

      override fun visitAnnotationArrayInitializer(initializer: PsiArrayInitializerMemberValue) {
        initializer.initializers.filterIsInstance<PsiLiteralExpression>().forEach {
          visitLiteralExpression(it)
        }
        super.visitAnnotationArrayInitializer(initializer)
      }

      override fun visitLiteralExpression(expression: PsiLiteralExpression) {
        val text = expression.text.drop(1).dropLast(1)
        val nodes = XmllessMethodAnnotationHighlighter.Util.parseExpression(text)
        var s = text
        nodes.forEach {
          if (it::class.java.simpleName == "Operator") {
            s = s.replaceRange(it.start, it.end + 1, it.toSql().uppercase())
          }
        }
        val literalExpression =
            JavaPsiFacade.getElementFactory(expression.project).createExpressionFromText("\"$s\"", null)
        if (literalExpression is PsiLiteralExpression) {
          expression.replace(literalExpression)
        }
      }

    })
    return TextRange(0, source.endOffset)
  }

}
